

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//反射的意义：在运行的时候可以动态的获取当前对象的一些的信息
public class ReflectClassDemo {
    //反射的使用，假设现在要反射Student类里面的东西

    public static void reflectNewInstance() throws ClassNotFoundException,
            InstantiationException, IllegalAccessException{
        //反射第一步，首先获取一个Class的对象（使用的是三种方式使用最多的一种）
        Class<?> c1 = Class.forName("Student");//受查异常，编译时异常
        //创建对象
        Student student = (Student)c1.newInstance();

        System.out.println(student);
    }




    //反射私有的带参数的构造方法
    public static void reflectPrivateConstructor() {
        try {
            Class<?> c1 = Class.forName("Student");
            //c1.getDeclaredConstructor拿到私有的
            Constructor<?> constructor = c1.getDeclaredConstructor(String.class,int.class);

            //因为是私有的，所有要指定一个ture，之后进呢修改了（私有的在内外不能修改）
            constructor.setAccessible(true);
            //修改了姓名和年龄
            Student student = (Student) constructor.newInstance("yamimi",18);

            System.out.println(student);

        }catch (NoSuchMethodException e){
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }


    //反射私有属性（在这调用name）
    public static void reflectPrivateField() {

        try {
            Class<?> c1 = Class.forName("Student");
            //创建对象
            Student student = (Student)c1.newInstance();

            //修改name
            Field field = c1.getDeclaredField("name");
            field.setAccessible(true);
            field.set(student,"yxx");

            System.out.println(student);

        }catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }


    //反射私有方法
    public static void reflectPrivateMethod() {
        try {
            Class<?> c1 = Class.forName("Student");
            //创建对象
            Student student = (Student)c1.newInstance();

            Method method = c1.getDeclaredMethod("function",String.class);
            method.setAccessible(true);
            method.invoke(student,"反射私有方法");

        }catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        reflectPrivateMethod();
    }


    public static void main3(String[] args) {
        reflectPrivateField();
    }



    public static void main2(String[] args) {
        reflectPrivateConstructor();
    }

    public static void main1(String[] args) {
        try{
            reflectNewInstance();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

